﻿#include <iostream>
using namespace std;

#include "listensocket.h"
#include "socketlibfunction.h"
#include "abstractpoll.h"

SocketLib::ListenSocket::ListenSocket()
{
    m_poll = NULL;
}

bool SocketLib::ListenSocket::listen(int aPort, int aBacknum)
{
    if (isValid())
    {
        return false;
    }

    m_fd = SocketApi::MakeListen(aPort, aBacknum);
    if (isValid())
    {
        setNoBlock(false);
        cout << "Listen Port:" << aPort << "Sucess" << endl;
        return true;
    }
    else
    {
        cout << "Listen Port:" << aPort << "Failed" << endl;
        return false;
    }
}

bool SocketLib::ListenSocket::onRead()
{
    sock s = SOCKET_ERROR;
    struct sockaddr_in socketaddress;
    socklen_t size = sizeof(struct sockaddr);
    s = accept( m_fd, (struct sockaddr*)&socketaddress, &size);

    if (SOCKET_ERROR == s)
    {
        return false;
    }

    SocketFD*    socketfd = getFreeSocketFD();
    if (NULL != socketfd)
    {
        socketfd->setSocketFD(s);
        socketfd->setNoBlock(false);
        m_poll->addSocketFD(socketfd);

        socketfd->onConnection();
    }
    else
    {
        SocketApi::CloseSocket(s);
    }

    return true;
}

void SocketLib::ListenSocket::addFreeSocketFD(SocketFD*    pSocketFD)
{
    if (this != pSocketFD)
    {
        m_freeList.push_back(pSocketFD);
    }
}

void SocketLib::ListenSocket::setPoll(SocketFDPoll* pPoll)
{
    if (NULL == m_poll)
    {
        m_poll = pPoll;
    }

}

void SocketLib::ListenSocket::disSocketFD(SocketFD* pSocketFD)
{
    if (NULL != m_poll)
    {
        m_poll->delSocketFD(pSocketFD);
        SocketLib::SocketApi::CloseSocket(pSocketFD->getSocketFD());
        addFreeSocketFD(pSocketFD);
    }
}

SocketLib::SocketFD* SocketLib::ListenSocket::getFreeSocketFD()
{
    if (m_freeList.empty())
    {
        return    NULL;
    }

    SocketFD* ret = *(m_freeList.begin());
    m_freeList.pop_front();
    ret->init();
    return ret;
}
